home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Collections: Scope
/
Scope Disk #157 (199x)(Scope PD)(US)[WB].zip
/
Scope Disk #157 (199x)(Scope PD)(US)[WB].adf
/
LockDevice
/
LockDevice-Handler.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-10-25
|
6KB
|
299 lines
/* $Revision Header * Header built automatically - do not edit! *************
*
* (C) Copyright 1990 by MXM
*
* Name .....: LockDevice-Handler.c
* Created ..: Tuesday 26-Jun-90 14:19
* Revision .: 1
*
* Date Author Comment
* ========= ======== ====================
* 26-Jun-90 Olsen Created this file!
*
* $Revision Header ********************************************************/
/* Global lock segment. */
struct LockSeg *LSeg;
/* Prototypes. */
BYTE StrCmp(char *a,char *b);
struct FileSysStartupMsg * FindDevice(char *DevName);
BYTE CreatePatch(char *DeviceName,char *PassWord);
extern VOID NewBeginIO(VOID);
VOID * PatchedBeginIO(struct IOExtTD *Request);
LONG _main(VOID);
/* StrCmp(char *a,char *b):
*
* Do a string comparison ignoring case.
*/
BYTE
StrCmp(char *a,char *b)
{
for( ; toupper(*a) == toupper(*b) ; a++, b++)
{
if(!(*a))
return(0);
}
return(1);
}
/* FindDevice(char *DevName):
*
* Find the environment data for filing system device.
*/
struct FileSysStartupMsg *
FindDevice(char *DevName)
{
char *Pointer,Name[257];
struct DeviceNode *DevInfo;
SHORT i;
Forbid();
DevInfo = (struct DeviceNode *)BADDR(((struct DosInfo *)BADDR(((struct RootNode *)DOSBase -> dl_Root) -> rn_Info)) -> di_DevInfo);
while(DevInfo)
{
if(DevInfo -> dn_Type == DLT_DEVICE && DevInfo -> dn_Task && !DevInfo -> dn_Handler)
{
Pointer = (char *)BADDR(DevInfo -> dn_Name);
for(i = 0 ; i < Pointer[0] ; i++)
Name[i] = Pointer[i + 1];
Name[Pointer[0] ] = ':';
Name[Pointer[0] + 1] = 0;
if(!StrCmp(Name,DevName))
{
Permit();
return(BADDR(DevInfo -> dn_Startup));
}
}
DevInfo = (struct DeviceNode *)BADDR(DevInfo -> dn_Next);
}
Permit();
return(NULL);
}
/* CreatePatch(char *DeviceName,char *PassWord):
*
* Create a BeginIO patch for a given filing device.
*/
BYTE
CreatePatch(char *DeviceName,char *PassWord)
{
struct Patch *NewPatch,*TempPatch = LSeg -> RootPatch;
struct FileSysStartupMsg *Startup;
char *DriverName;
/* Try to find the environment vector. */
if(Startup = FindDevice(DeviceName))
{
/* Allocate memory for the patch. */
if(NewPatch = (struct Patch *)AllocMem(sizeof(struct Patch),MEMF_PUBLIC | MEMF_CLEAR))
{
/* Allocate memory for the IORequest. */
if(NewPatch -> Request = (struct IOExtTD *)AllocMem(sizeof(struct IOExtTD),MEMF_PUBLIC | MEMF_CLEAR))
{
NewPatch -> Request -> iotd_Req . io_Message . mn_Node . ln_Type = NT_MESSAGE;
NewPatch -> Request -> iotd_Req . io_Message . mn_Length = sizeof(struct IOExtTD);
/* Remember the name of the device driver. */
DriverName = (char *)((ULONG)BADDR(Startup -> fssm_Device) + 1);
/* Open the device driver. */
if(!OpenDevice(DriverName,Startup -> fssm_Unit,NewPatch -> Request,Startup -> fssm_Flags))
{
/* Remember the device pointer. */
NewPatch -> Device = NewPatch -> Request -> iotd_Req . io_Device;
/* Copy the password. */
if(PassWord)
strcpy(NewPatch -> PassWord,PassWord);
/* Copy the name of the filing device. */
strcpy(NewPatch -> UnitName,DeviceName);
/* Copy the name of the device driver. */
strcpy(NewPatch -> DriverName,DriverName);
Disable();
/* Remember old BeginIO vector. */
NewPatch -> OldBeginIO = (VOID *)SetFunction((struct Library *)NewPatch -> Device,DEV_BEGINIO,NewBeginIO);
/* Add the patch to the patch list. */
while(TempPatch)
{
if(!TempPatch -> NextPatch)
{
TempPatch -> NextPatch = NewPatch;
Enable();
return(TRUE);
}
TempPatch = TempPatch -> NextPatch;
}
LSeg -> RootPatch = NewPatch;
Enable();
return(TRUE);
}
FreeMem(NewPatch -> Request,sizeof(struct IOExtTD));
}
FreeMem(NewPatch,sizeof(struct Patch));
}
}
return(FALSE);
}
/* PatchedBeginIO(struct IOExtTD *Request):
*
* Our patched BeginIO routine. Note: this code is
* shared between a number of calling tasks and has
* to be reentrant.
*/
VOID *
PatchedBeginIO(struct IOExtTD *Request)
{
struct Patch *Patch = LSeg -> RootPatch;
VOID *JumpAddress = NULL;
Disable();
/* Find the patch for this device. */
while(Patch)
{
if(Patch -> Device == Request -> iotd_Req . io_Device)
break;
Patch = Patch -> NextPatch;
}
/* Got it! Remember the old BeginIO vector. */
if(Patch)
JumpAddress = Patch -> OldBeginIO;
Enable();
if(!Patch)
Request -> iotd_Req . io_Error = TDERR_NotSpecified;
else
{
switch(Request -> iotd_Req . io_Command & ~TDF_EXTCOM)
{
/* Reject illegal commands. */
case CMD_WRITE:
case TD_FORMAT:
case TD_RAWWRITE: Request -> iotd_Req . io_Error = TDERR_WriteProt;
return(NULL);
/* Disk is write protected. */
case TD_PROTSTATUS: Request -> iotd_Req . io_Error = 0;
Request -> iotd_Req . io_Actual = ~0;
return(NULL);
default: break;
}
}
/* Return to the interface code. */
return(JumpAddress);
}
/* _main():
*
* Handler entry point.
*/
LONG
_main()
{
struct Process *ThisProcess = (struct Process *)SysBase -> ThisTask;
ULONG SignalSet;
/* Called from shell? */
if(ThisProcess -> pr_CLI || !(LSeg = (struct LockSeg *)FindPort(PORTNAME)))
return(-1);
/* Initialize the global MsgPort. */
LSeg -> SignalPort . mp_SigBit = SIGBREAKB_CTRL_E;
LSeg -> SignalPort . mp_SigTask = ThisProcess;
LSeg -> SignalPort . mp_Flags = PA_SIGNAL;
/* Add the child entry and ring back. */
LSeg -> Child = (struct Task *)ThisProcess;
Signal(LSeg -> Father,LSeg -> HandShake);
for(;;)
{
SignalSet = Wait(SIG_PORT | SIG_QUIT);
/* A new patch request came in. */
if(SignalSet & SIG_PORT)
{
struct LockMsg *Message;
while(Message = (struct LockMsg *)GetMsg(&LSeg -> SignalPort))
{
Message -> Success = CreatePatch(Message -> DeviceName,Message -> PassWord);
ReplyMsg((struct Message *)Message);
}
}
/* Deallocate the handler. */
if(SignalSet & SIG_QUIT)
{
LSeg -> Child = NULL;
Forbid();
Signal(LSeg -> Father,LSeg -> HandShake);
return(0);
}
}
}